

#include <stdio.h>
#include "huffman/huffman.h"


#define ComprMaxCadeia 5000
#define ComprMaxCadeiaBits 10000
#define ComprMaxLinha 100

void IgnoraLinha() 
{
	/* Ignora o resto da linha */
	char c;
	do 
	{ 
		scanf("%c", &c); 
	} while (c !='\n');
	return;
}

Boolean LeCadeia(char *s) 
{
	/* L� e concatena as linhas de entrada numa �nica cadeia na �rea
   apontada por 's'; sup�e que a �rea j� existe. Se o comprimento de
   alguma linha ultrapassar 'ComprMaxLinha-2', ela � truncada (veja a
   defini��o da fun��o 'fgets').  Devolve 'true' em caso de sucesso;
   devolve 'false' se o comprimento da cadeia ultrapassar
   'ComprMaxCadeia'.  */

	int comprLinha, comprCadeia=0;
	char linha[ComprMaxLinha];

	*s = '\0';   /* cadeia vazia */

	while(fgets(linha,ComprMaxLinha,stdin)!=NULL) 
	{
		comprLinha = strlen(linha)-1;
		linha[comprLinha] = '\0';  /* elimina '\n' que � lido por 'fgets' */
		comprCadeia += comprLinha;

		if (comprCadeia>=ComprMaxCadeia)
		{
			return false;
		}

		strcat(s,linha);
	}

	return true;

} /* LeCadeia */

void EscreveCadeia(char *s) 
{
	/* Escreve os caracteres da cadeia 's', 'ComprMaxLinha' por linha;
   a �ltima linha pode ser mais curta. */

	int comprCadeia = strlen(s);
	int comprLinha = 0;
	char *ultimoCar = s + comprCadeia;  /* aponta para '\0' final */

	while (s<ultimoCar) 
	{
		if (comprLinha==ComprMaxLinha) 
		{
			printf("\n");
			comprLinha=0;
		}
		printf("%c",*s);
		s++;
		comprLinha++;
	}

} /* EscreveCadeia */


int ReadByteFrequency(FILE * fileToBeCompressed, int *freq[])
{
	char c;

	//put the file pointer at the beginning
	rewind (fileToBeCompressed);

	//read every byte and update the frequency table.
	while (fread(&c, sizeof(char), 1, fileToBeCompressed))
	{
		freq[c]++;
	}
}

int main(int argc, char *argv[])
{
	int freq[SIZE_AMOSTRAL_SPACE];
	int tamAlfabeto;
	char cars[ComprMaxCadeia];
	char bits[ComprMaxCadeiaBits];
	char aux[ComprMaxCadeia];
	int i,numBits,comprCadeia;

	FILE *fileToBeCompressed;


	if (argc != 2)
	{
		printf("You must enter a file.\n\nUsage: ./dcompactor -c file_to_be_compressed");
		return 1;
	}

	fileToBeCompressed = fopen(argv[1], "r");

	if (fileToBeCompressed == NULL)
	{
		printf("Invalid File!");
		return 1;
	}

	for (i=0; i<SIZE_AMOSTRAL_SPACE; i++)
	{
		freq[i] = 0;
	}

	if (ReadByteFrequency(fileToBeCompressed, freq))
	{
		printf("Error handling file");
		return 1;
	}

	for (i=0; i<SIZE_AMOSTRAL_SPACE; i++)
	{
		printf("byte %d: %d\n", i, freq[i]);
	}

	/* Inicializa estruturas */
	if(ConstroiHuffman(freq, SIZE_AMOSTRAL_SPACE)) 
	{
		printf("\nHuffman Tree:\n\n");
		//ImprimeArvore();
	} 
	else 
	{
		printf("\nN�o foi poss�vel construir a �rvore\n");
		return 0;
	}

	/* L� dados e comprime */
	if (!LeCadeia(cars)) 
	{
		printf("Problemas com o arquivo de entrada\n");
		return 1;
	}

	printf("\nCadeia de Entrada:\n");
	EscreveCadeia(cars);
	printf("\n");

	if (!Comprime(cars,bits,&numBits,ComprMaxCadeiaBits-1)) 
	{
		printf("Dados inv�lidos\n");
		return 1;
	}

	/* Exibe e verifica resultados */

	/* Faz teste inverso */
	if (!Descomprime(aux,bits,numBits,ComprMaxCadeia)) 
	{
		printf("Problemas na descompress�o\n");
		return 1;
	}

	comprCadeia = strlen(cars);


	printf("\nCadeia dada: %d bytes\nCadeia comprimida: %d bits (%d bytes)\nM�dia: %2.1f bits/caractere\n",
			comprCadeia,numBits,(numBits-1)/8+1,(float)numBits/(float)comprCadeia);
	printf("\nCadeia comprimida:\n");
	bits[numBits] = '\0';
	EscreveCadeia(bits);
	printf("\n");
	printf("\nCadeia descomprimida:\n%s\n",aux);


	if (strcmp(cars,aux)==0) 
	{
		printf("\nResultados corretos\n");
	}
	else
	{
		printf("\nResultados errados\n");
	}

	LiberaHuffman();

	/* Finaliza��o */

	//FINISH_MALLOC();

	printf("\nProcessamento terminado\n");

	return 0;

}
